﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Foundation.Collections;

namespace FASTControlUI
{

    public class ConfigManager<T>
    {
        public static string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\FASTControlUI\\Data";
        public Configuration config;
        public static string MainConfig = "MainConfig";
        public static string UserConfig = "UserConfig";

        public ConfigManager()
        {
            config = GetConfig();
        }
        public ConfigManager(string ConfigName)
        {
            config = GetConfig(ConfigName);
        }
        public static object Converter(Type type, string value)
        {
            return Convert.ChangeType(value, type);
        }
        static T BytesToStruct(byte[] bytes)
        {
            int size = Marshal.SizeOf<T>();
            IntPtr point = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(bytes, 0, point, size);
                return Marshal.PtrToStructure<T>(point);
            }
            finally
            {
                Marshal.FreeHGlobal(point);
            }
        }
        static byte[] StructToBytes(T t)
        {
            int size = Marshal.SizeOf<T>();
            byte[] bytes = new byte[size];
            IntPtr point = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr<T>(t, point, false);
                Marshal.Copy(point, bytes, 0, size);
                return bytes;
            }
            finally
            {
                Marshal.FreeHGlobal(point);
            }
        }
        public static Configuration GetConfig()
        {
            return ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        }
        static Configuration GetConfig(string ConfigName)
        {
            ExeConfigurationFileMap configFile = new ExeConfigurationFileMap() { ExeConfigFilename = Path.Combine(path, ConfigName + ".config") };
            return ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
        }
        public string GetKey(string key)
        {
            if (config.AppSettings.Settings.AllKeys.Contains(key))
                return config.AppSettings.Settings[key].Value;
            else
                return null;
        }
        public void SetKey(string key, string value)
        {
            if (config.AppSettings.Settings.AllKeys.Contains(key))
                config.AppSettings.Settings[key].Value = value;
            else
                config.AppSettings.Settings.Add(key, value);
            config.AppSettings.SectionInformation.ForceSave = true;
            config.Save(ConfigurationSaveMode.Modified);
        }
        public T this[string key]
        {
            get
            {
                if (config.AppSettings.Settings.AllKeys.Contains(key))
                    return BytesToStruct(Convert.FromBase64String(config.AppSettings.Settings[key].Value));
                else
                    return default;
            }
            set
            {
                if (config.AppSettings.Settings.AllKeys.Contains(key))
                {
                    config.AppSettings.Settings[key].Value = Convert.ToBase64String(StructToBytes(value));
                }
                else
                {
                    config.AppSettings.Settings.Add(key, Convert.ToBase64String(StructToBytes(value)));
                }
                config.AppSettings.SectionInformation.ForceSave = true;
                try
                {
                    config.Save(ConfigurationSaveMode.Modified);
                }
                catch (ConfigurationException)
                {
                    config = GetConfig(MainConfig);
                    config.Save(ConfigurationSaveMode.Modified);
                }
            }
        }
    }
}
